package SCADA;

import java.io.IOException;
import java.net.UnknownHostException;
import java.util.Iterator;
import java.util.List;
import java.util.LinkedList;

import automatas.*;
import componentesFisicos.*;
import comunicaciones.*;
import eventos.*;
import gui.*;
import informes.*;


public class SCADA implements Automata{
	
	private GestorInformes gi;
	private GestorParametros gp;
	private int cicloReloj;
	private final String nombre="SCADA";
	
	//interfaz
	ControladoraGrafica controladora;
	IPrincipal interfaz; 
	
	
	//Cominicacion
	private String nombre_maestro;
	private String nombreMaestro;
	private String nombre_esclavo1;
	private String nombre_esclavo2;
	private String nombre_esclavo3;
	private static int PUERTO=50000;
	private IBuzon buzon;
	
	//Listas de mensajes auxiliares
	protected List<Mensaje> listaSalida;
	
	//tick de reloj
	Reloj miReloj;
	Thread hiloReloj;
	
	public SCADA(){
		gi = new GestorInformes();
		gp = new GestorParametros();
	}
	
	public SCADA(String nombre_maestro, String nombreMaestro, String nombre_esclavo1, 
			String nombre_esclavo2, String nombre_esclavo3, int ciclo){
		gi = new GestorInformes();
		gp = new GestorParametros();
		//this.PUERTO=puerto;
		this.nombre_maestro=nombre_maestro;
		this.nombreMaestro=nombreMaestro;
		this.listaSalida=new LinkedList<Mensaje>();
		this.cicloReloj=ciclo;
		this.nombre_esclavo3=nombre_esclavo3;
		this.nombre_esclavo1=nombre_esclavo1;
		this.nombre_esclavo2=nombre_esclavo2;
		this.miReloj=new Reloj(this.cicloReloj, this);
		controladora=new ControladoraGrafica();
		//JPanelImage panelImagen = new JPanelImage("cinta1_0.jpg");
		this.interfaz = this.controladora.getPanel();
		interfaz.getFrame().setVisible(true);
		//this.hiloReloj=new Thread(this.miReloj);
		this.iniciarComunicaciones(this.nombre);
		this.getBuzon().addMensajeEventListener(new MensajeEventListenerSCADA(this, null));
		//controladora=new ControladoraGrafica();
		//this.interfaz = this.controladora.getPanel();
		//interfaz.getFrame().setVisible(true);
	}
	
	public boolean establecerBuzon(IBuzon buzon){
		setBuzon(buzon);
		if(buzon!=null)
			return true;
		else
			return false;
	}
	protected void iniciarComunicaciones(String nombre){
		// TODO Auto-generated method stub
		ClienteBuzon cliente = new ClienteBuzon(nombre_maestro,nombre,PUERTO);
		try{
			cliente.iniciarCliente(this);
		}catch(IOException e){
			System.out.println("Automata "+nombre+"-: Error al iniciar las comunicaciones con el Automata Esclavo." );
		}
	}
	
	public void enviarMensajesAcumulados(){
		Iterator<Mensaje> it = this.listaSalida.iterator();
    	while(it.hasNext()){
    		this.escribirMensaje((it.next()));
    	}
    	this.listaSalida.clear();
	}
	
	public boolean escribirMensaje(Mensaje mensaje){
		if(buzon == null)
			return false;
		return buzon.escribir(mensaje);
	}	

	public Mensaje leerMensaje(){
		if(buzon == null)
			return null;
		return buzon.leer();
	}
	public Mensaje leerMensaje(String nombre){
		return this.leerMensaje();
	}
	public Mensaje leerBroadcast(){
		return this.leerMensaje();
	}
	
	public void despertar(){}
	public void esperar(){}
	
	
	
	
	public void aumentarBlisteresCorrectos(){
		gi.aumentarBlisteresCorrectos();
	}
	
	public void aumentarBlisteresDefectuosos(){
		gi.aumentarBlisteresDefectuosos();
	}
	
	public void aumentarPastelesCorrectos(){
		gi.aumentarPastelesCorrectos();
	}
	
	public void aumentarPastelesDefectuosos(){
		gi.aumentarPastelesDefectuosos();
	}
	
	public void aumentarArranques(){
		gi.aumentarArranques();
	}
	
	public void aumentarEmergencia(){
		gi.aumentarEmergencia();
	}
	
	public void aumentarNormales(){
		gi.aumentarNormales();
	}
	
	public void aumentarFallo(){
		gi.aumentarFallo();
	}
	
	public String obtenerInformeBlisteres(){
		return gi.obtenerInformeBlisteres();
	}
	
	public String obtenerInformePasteles(){
		return gi.obtenerInformePasteles();
	}
	
	public String obtenerInformeParadas(){
		return gi.obtenerInformeParadas();
	}
	
	public void generarInformePasteles(){
		gi.generarInformePasteles();
	}
	
	public void generarInformeBlisteres(){
		gi.generarInformeBlisteres();
	}
	
	public void generarInformeParadas(){
		gi.generarInformeParadas();
	}
	
	public void cambiarParametrosA1(int LC, int VC, int CDP, int TAVChoc, int TAVCar){
		gp.cambiarA1(LC, VC, CDP, TAVChoc, TAVCar);
	}
	
	public void cambiarParametrosA2(int LC, int VC){
		gp.cambiarA2(LC, VC);
	}
	
	public void cambiarParametrosA3(int LC, int VC, int TAS){
		gp.cambiarA3(LC, VC, TAS);
	}
	
	public void cambiarParametrosR(int TRB, int TTC, int TTB){
		gp.cambiarRobots(TRB, TTC, TTB);
	}
	
	public void cambiarParametrosOtros(int CR, int UDF){
		gp.cambiarOtros(CR, UDF);
	}
	
	public void restaurarValoresPorDefecto(){
		gp.restaurarValoresDefecto();
	}
	
	public void restaurarUltimosValores(){
		gp.restaurarUltimosValores();
	}
	
	public int[] obtenerParametros(){
		return gp.obtenerParametros();
	}
	
	public int getA1LongitudCinta() {
		return gp.getA1LongitudCinta();
	}

	public void setA1LongitudCinta(int longitudCinta) {
		gp.setA1LongitudCinta(longitudCinta);
	}

	public int getA1VelocidadCinta() {
		return gp.getA1VelocidadCinta();
	}

	public void setA1VelocidadCinta(int velocidadCinta) {
		gp.setA1VelocidadCinta(velocidadCinta);
	}

	public int getA1CapacidadDepositoPasteles() {
		return gp.getA1CapacidadDepositoPasteles();
	}

	public void setA1CapacidadDepositoPasteles(int capacidadDepositoPasteles) {
		gp.setA1CapacidadDepositoPasteles(capacidadDepositoPasteles);
	}

	public int getA1TiempoActivacionValvulaChocolate() {
		return gp.getA1TiempoActivacionValvulaChocolate();
	}

	public void setA1TiempoActivacionValvulaChocolate(int tiempoActivacionValvulaChocolate) {
		gp.setA1TiempoActivacionValvulaChocolate(tiempoActivacionValvulaChocolate);
	}

	public int getA1TiempoActivacionValvulaCaramelo() {
		return gp.getA1TiempoActivacionValvulaCaramelo();
	}

	public void setA1TiempoActivacionValvulaCaramelo(int tiempoActivacionValvulaCaramelo) {
		gp.setA1TiempoActivacionValvulaCaramelo(tiempoActivacionValvulaCaramelo);
	}

	public int getA2LongitudCinta() {
		return gp.getA2LongitudCinta();
	}

	public void setA2LongitudCinta(int longitudCinta) {
		gp.setA2LongitudCinta(longitudCinta);
	}

	public int getA2VelocidadCinta() {
		return gp.getA2VelocidadCinta();
	}

	public void setA2VelocidadCinta(int velocidadCinta) {
		gp.setA2VelocidadCinta(velocidadCinta);
	}

	public int getA3LongitudCinta() {
		return gp.getA3LongitudCinta();
	}

	public void setA3LongitudCinta(int longitudCinta) {
		gp.setA3LongitudCinta(longitudCinta);
	}

	public int getA3VelocidadCinta() {
		return gp.getA3VelocidadCinta();
	}

	public void setA3VelocidadCinta(int velocidadCinta) {
		gp.setA3VelocidadCinta(velocidadCinta);
	}

	public int getA3TiempoActivacionSelladora() {
		return gp.getA3TiempoActivacionSelladora();
	}

	public void setA3TiempoActivacionSelladora(int tiempoActivacionSelladora) {
		gp.setA3TiempoActivacionSelladora(tiempoActivacionSelladora);
	}

	public int getR1TiempoRecogidaBlister() {
		return gp.getR1TiempoRecogidaBlister();
	}

	public void setR1TiempoRecogidaBlister(int tiempoRecogidaBlister) {
		gp.setR1TiempoRecogidaBlister(tiempoRecogidaBlister);
	}

	public int getR1TiempoTransporteColocacion() {
		return gp.getR1TiempoTransporteColocacion();
	}

	public void setR1TiempoTransporteColocacion(int tiempoTransporteColocacion) {
		gp.setR1TiempoTransporteColocacion(tiempoTransporteColocacion);
	}

	public int getR2TiempoTransporteBlister() {
		return gp.getR2TiempoTransporteBlister();
	}

	public void setR2TiempoTransporteBlister(int tiempoTransporteBlister) {
		gp.setR2TiempoTransporteBlister(tiempoTransporteBlister);
	}

	public int getCicloDeReloj() {
		return gp.getCicloDeReloj();
	}

	public void setCicloDeReloj(int cicloDeReloj) {
		gp.setCicloDeReloj(cicloDeReloj);
	}

	public int getUmbralDeFallo() {
		return gp.getUmbralDeFallo();
	}

	public void setUmbralDeFallo(int umbralDeFallo) {
		gp.setUmbralDeFallo(umbralDeFallo);
	}
	
	public void arrancar(){
		Mensaje dev = new Mensaje(null, this.nombreMaestro);
		dev.setMatrizMensaje(0,true);
		dev.setMatrizMensaje(10,true);
		dev.setMatrizMensaje(15,true);
		this.aumentarArranques();
		listaSalida.add(dev);
	}
	
	public void paradaNormal(){
		Mensaje dev = new Mensaje(null, this.nombreMaestro);
		dev.setMatrizMensaje(0,true);
		dev.setMatrizMensaje(5,true);
		this.aumentarNormales();
		listaSalida.add(dev);
	}
	
	public void paradaEmergencia(){
		Mensaje dev = new Mensaje(null, this.nombreMaestro);
		dev.setMatrizMensaje(0, true);
		dev.setMatrizMensaje(7, true);
		this.aumentarEmergencia();
		listaSalida.add(dev);
	}
	
	public void paradaSimulacion(){
		Mensaje dev = new Mensaje(null, this.nombreMaestro);
		dev.setMatrizMensaje(0, true);
		dev.setMatrizMensaje(14, true);
		listaSalida.add(dev);
	}
	
	public void rellenarPasteles(){
		Mensaje dev = new Mensaje(null, this.nombre_esclavo1);
		dev.setMatrizMensaje(0, true);
		dev.setMatrizMensaje(11, true);
		listaSalida.add(dev);
	}
	
	public void rellenarChocolate(){
		Mensaje dev = new Mensaje(null, this.nombre_esclavo1);
		dev.setMatrizMensaje(0, true);
		dev.setMatrizMensaje(12, true);
		listaSalida.add(dev);
	}
	
	public void rellenarCaramelo(){
		Mensaje dev = new Mensaje(null, this.nombre_esclavo1);
		dev.setMatrizMensaje(0, true);
		dev.setMatrizMensaje(13, true);
		listaSalida.add(dev);
	}
	
	public void enviarParametrosCinta1(){
				
		Mensaje dev = new Mensaje(gp.getCicloDeReloj(), this.nombre_esclavo1);
		Mensaje dev1 = new Mensaje(gp.getA1LongitudCinta(), this.nombre_esclavo1);
		Mensaje dev2 = new Mensaje(gp.getA1VelocidadCinta(), this.nombre_esclavo1);
		Mensaje dev3 = new Mensaje(gp.getA1CapacidadDepositoPasteles(), this.nombre_esclavo1);
		Mensaje dev4 = new Mensaje(gp.getA1TiempoActivacionValvulaChocolate(), this.nombre_esclavo1);
		Mensaje dev5 = new Mensaje(gp.getA1TiempoActivacionValvulaCaramelo(), this.nombre_esclavo1);
		
		
		//dev.setMatrizMensaje(1, false);
		//dev.setMatrizMensaje(2, false);
		//dev.setMatrizMensaje(3, false);
		
		
		dev1.setMatrizMensaje(1, false);
		dev1.setMatrizMensaje(2, false);
		dev1.setMatrizMensaje(3, true);
		
		
		dev2.setMatrizMensaje(1, false);
		dev2.setMatrizMensaje(2, true);
		dev2.setMatrizMensaje(3, false);
		
		
		dev3.setMatrizMensaje(1, false);
		dev3.setMatrizMensaje(2, true);
		dev3.setMatrizMensaje(3, true);
		
		
		dev4.setMatrizMensaje(1, true);
		dev4.setMatrizMensaje(2, false);
		dev4.setMatrizMensaje(3, false);
		
		
		dev5.setMatrizMensaje(1, true);
		dev5.setMatrizMensaje(2, false);
		dev5.setMatrizMensaje(3, true);		
		
		//listaSalida.add(dev);
		listaSalida.add(dev1);
		listaSalida.add(dev2);
		listaSalida.add(dev3);
		listaSalida.add(dev4);
		listaSalida.add(dev5);
		
	}
	
	public void enviarParametrosCinta2(){
		
		
		Mensaje dev = new Mensaje(gp.getCicloDeReloj(), this.nombre_esclavo2);
		Mensaje dev1 = new Mensaje(gp.getA2LongitudCinta(), this.nombre_esclavo2);
		Mensaje dev2 = new Mensaje(gp.getA2VelocidadCinta(), this.nombre_esclavo2);
		
		
		//dev.setMatrizMensaje(1, false);
		//dev.setMatrizMensaje(2, false);
		//dev.setMatrizMensaje(3, false);
		
		
		dev1.setMatrizMensaje(1, false);
		dev1.setMatrizMensaje(2, false);
		dev1.setMatrizMensaje(3, true);
		
		
		dev2.setMatrizMensaje(1, false);
		dev2.setMatrizMensaje(2, true);
		dev2.setMatrizMensaje(3, false);
	
		//listaSalida.add(dev);
		listaSalida.add(dev1);
		listaSalida.add(dev2);
				
		
	}
	
	public void enviarParametrosCinta3(){
		
		Mensaje dev = new Mensaje(gp.getCicloDeReloj(), this.nombre_esclavo3);
		Mensaje dev1 = new Mensaje(gp.getA3LongitudCinta(), this.nombre_esclavo3);
		Mensaje dev2 = new Mensaje(gp.getA3VelocidadCinta(), this.nombre_esclavo3);
		Mensaje dev3 = new Mensaje(gp.getA3TiempoActivacionSelladora(), this.nombre_esclavo3);
		
		
		//dev.setMatrizMensaje(1, false);
		//dev.setMatrizMensaje(2, false);
		//dev.setMatrizMensaje(3, false);
		
		
		dev1.setMatrizMensaje(1, false);
		dev1.setMatrizMensaje(2, false);
		dev1.setMatrizMensaje(3, true);
		
		
		dev2.setMatrizMensaje(1, false);
		dev2.setMatrizMensaje(2, true);
		dev2.setMatrizMensaje(3, false);
		
		
		dev3.setMatrizMensaje(1, false);
		dev3.setMatrizMensaje(2, true);
		dev3.setMatrizMensaje(3, true);
				
		//this.listaSalida.add(dev);
		this.listaSalida.add(dev1);
		this.listaSalida.add(dev2);
		this.listaSalida.add(dev3);
	}
	
	public void enviarParametrosRobots(){
		
		Mensaje dev = new Mensaje(gp.getCicloDeReloj(), this.nombreMaestro);
		Mensaje dev1 = new Mensaje(gp.getR1TiempoRecogidaBlister(), this.nombreMaestro);
		Mensaje dev2 = new Mensaje(gp.getR1TiempoTransporteColocacion(), this.nombreMaestro);
		Mensaje dev3 = new Mensaje(gp.getR2TiempoTransporteBlister(), this.nombre_esclavo3);
		
		//dev.setMatrizMensaje(1, false);
		//dev.setMatrizMensaje(2, false);
		//dev.setMatrizMensaje(3, false);
		
		
		dev1.setMatrizMensaje(1, false);
		dev1.setMatrizMensaje(2, false);
		dev1.setMatrizMensaje(3, true);
		
		
		dev2.setMatrizMensaje(1, false);
		dev2.setMatrizMensaje(2, true);
		dev2.setMatrizMensaje(3, false);
		
		
		dev3.setMatrizMensaje(1, true);
		dev3.setMatrizMensaje(2, false);
		dev3.setMatrizMensaje(3, false);
		
		//this.listaSalida.add(dev);
		this.listaSalida.add(dev1);
		this.listaSalida.add(dev2);
		this.listaSalida.add(dev3);
				
		
	}
	
	public void enviarParametrosOtros(){
				
		Mensaje dev = new Mensaje(gp.getCicloDeReloj(), this.nombreMaestro);
		Mensaje dev1 = new Mensaje(gp.getUmbralDeFallo(), this.nombre_esclavo3);
		
		//dev.setMatrizMensaje(1, false);
		//dev.setMatrizMensaje(2, false);
		//dev.setMatrizMensaje(3, false);
		
		
		dev1.setMatrizMensaje(1, true);
		dev1.setMatrizMensaje(2, false);
		dev1.setMatrizMensaje(3, true);
		

		this.listaSalida.add(dev);
		this.listaSalida.add(dev1);
				
		
	}

	public int getCicloReloj() {
		return cicloReloj;
	}

	public void setCicloReloj(int cicloReloj) {
		this.cicloReloj = cicloReloj;
	}

	public IBuzon getBuzon() {
		return buzon;
	}

	public void setBuzon(IBuzon buzon) {
		this.buzon = buzon;
	}

	public String getNombre() {
		return nombre;
	}
	public void run(){
		//this.hiloReloj.start();
		this.miReloj.iniciar();
	}
	

	/**
	 * @return the nombre_esclavo1
	 */
	public String getNombre_esclavo1() {
		return nombre_esclavo1;
	}

	/**
	 * @return the nombre_esclavo2
	 */
	public String getNombre_esclavo2() {
		return nombre_esclavo2;
	}

	/**
	 * @return the nombre_esclavo3
	 */
	public String getNombre_esclavo3() {
		return nombre_esclavo3;
	}
	

	/**
	 * @return the nombreMaestro
	 */
	public String getNombreMaestro() {
		return nombreMaestro;
	}

	@Override
	public Mensaje construirMensaje() {
		// TODO Auto-generated method stub
		return null;
	}
	
	public void activarSensor4A1(){
		controladora.encenderSensor4();
	}
	
	public void activarSensor1A1(){
		controladora.encenderSensor1();
	}
	public void activarSensor2A1(){
		controladora.encenderSensor2();
	}
	public void activarSensor3A1(){
		controladora.encenderSensor3();
	}
	public void desactivarSensor3A1(){
		controladora.apagarSensor3();
	}
	
	public void indicarChocolateMinimo(){
		controladora.indicarChocolateVacio();
	}
	
	public void indicarChocolateNormal(){
		controladora.indicarEstadoNormalChocolate();
	}
	public void indicarCarameloMinimo(){
		controladora.indicarCarameloVacio();
	}
	public void indicarCarameloNormal(){
		controladora.indicarEstadoNormalCaramelo();
	}
	public void desactivarSensor4A1(){
		controladora.apagarSensor4();
	}
	public void desactivarSensor2A1(){
		controladora.apagarSensor2();
	}
	public void desactivarSensor1A1(){
		controladora.apagarSensor1();
	}
	public void moverCinta1(){
		controladora.moverCinta1();
	}
	public void pararCinta1(){
		controladora.pararCinta1();
	}
	
	public void encencerDepositoBizcochos(){
		controladora.activarExpendedoraBizcochos();
		controladora.indicarBizcochosLleno();
	}
	public void apagarDepositoBizcochos(){
		controladora.indicarEstadoNormalBizcocho();
		
	}
	public void echarChocolate(){
		controladora.echarChocolate();
		controladora.indicarChocolateLleno();
	}
	public void echarCaramelo(){
		controladora.echarCaramelo();
		controladora.indicarCarameloLleno();
	}
	public void apagarDepositoCaramelo(){
		controladora.indicarEstadoNormalCaramelo();
		
	}
	public void moverBizcocho(double posicion){
		controladora.moverBizcocho(posicion);
		
	}
	
	public void ejectuarPasoRobot1(){
		controladora.ejecutarPasosRobot1();
	}
	public void apagarDepositoChocolate(){
		controladora.indicarEstadoNormalChocolate();
		
	}
	
	public void pintar(){
		controladora.pintar();
	}
	public static void main (String [] args){
		SCADA scada;
		String ip_maestro = null;
		try {
			ip_maestro = java.net.InetAddress.getLocalHost().getHostAddress();
			ip_maestro="163.117.142.219";
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			ip_maestro = "hector-hp";
		}
		
		scada = new SCADA(ip_maestro, "Maestro", "esclavo 1", "esclavo 2", "esclavo 3", 200);
		System.out.println("Scada iniciado");
		scada.miReloj.iniciar();
	}
	
	
	
}
